// #include "Shaders/Shared.h"
#include "Shaders/utility.hlsl"

// #define CUBE_SKYBOX

ConstantBuffer<Constants> constant : register(b0);

#ifdef CUBE_SKYBOX
TextureCube radianceIBLTexture : register(t0);
#else
Texture2D<float3> radianceIBLTexture : register(t0);
#endif

SamplerState defaultSampler : register(s0);

struct VSInput
{
    float3 position : POSITION;
    float3 normal : NORMAL;
    float2 uv : TEXCOORD;
};

struct PSInput
{
    float4 position : SV_POSITION;
    float3 normal : NORMAL;
    float2 uv : TEXCOORD0;
};

float3 DecodeRGBE8(float4 rgbe)
{
    float exponent = rgbe.a * 255.0f - 128.0f - 8.0f;
    return rgbe.rgb * exp2(exponent);
}

float3 MultiplyExposure(float3 rgbe)
{
    return rgbe.rgb * exp2(constant.ExposureKd.x);
}

PSInput VSMain(VSInput vin)
{
    PSInput result;
    vin.position -= float3(-0.253102, 0.654993, -0.172811);
    result.position = mul(constant.ViewProj, float4(vin.position.xyz, 1));
    result.normal = vin.normal;
    result.uv = vin.uv;

    return result;
}

float4 PSMain(PSInput input) : SV_TARGET
{
    // const float3 lightDir = float3(0.3f, 0.3f, -0.3f);
    // float color = max(0.1f, dot(lightDir, normalize(input.normal)));
    // return float4(color, color, color, 1.0);
    float2 uv = input.position.xy / constant.WidthHeight.xy;
    uv = uv * 2 - float2(1, 1);
    float4 worldPosH = mul(constant.InvViewProj, float4(uv.xy, input.position.z, 1));
    float3 revViewDir = normalize(worldPosH.xyz / worldPosH.w - constant.CameraPosTime.xyz);

    float3 reflectDir = reflect(revViewDir, input.normal);

    float2 radiance_uv = SampleSphericalMap(reflectDir);
    float3 rgb = radianceIBLTexture.Sample(defaultSampler, radiance_uv);
    return float4(MultiplyExposure(rgb), 1);
}

